package com.wans.guli.auth.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wans.guli.auth.feign.IntegrationFeignClient;
import com.wans.guli.auth.feign.MemberFeignClient;
import com.wans.guli.auth.vo.MemberRegisterVO;
import com.wans.guli.auth.vo.oauth.MemberVO;
import com.wans.guli.common.utils.R;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

@Controller
@Slf4j
public class RegisterAndLoginController {

    @Autowired
    private IntegrationFeignClient integrationFeignClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private MemberFeignClient memberFeignClient;
    @Autowired
    private ObjectMapper objectMapper;

    @GetMapping("/sms/sendCode")
    @ResponseBody
    public R sendCode(@RequestParam("phone") String phone) {
        // TODO 验证码防刷 - 服了 SMSController 里也写了一个排错排好久
/*        Boolean exist = stringRedisTemplate.opsForValue().setIfAbsent("sms:code:verify:" + phone, "exist", 1, TimeUnit.MINUTES);
        if (exist == null || !exist) return R.error("请勿重复发送验证码");*/


        // 随机生成验证码
        String code = RandomUtil.randomNumbers(6);
        stringRedisTemplate.opsForValue().set("sms:code:" + phone, code, 15, TimeUnit.MINUTES);


        log.info("发送验证码");
        integrationFeignClient.sendCode(phone, code);

        return R.ok();
    }


    @PostMapping(value = {"/register"})
    public String register(@Valid MemberRegisterVO memberVO, BindingResult bindingResult, Model model) {

        HashMap<String, String> errors = new HashMap<>();

        if (bindingResult.hasErrors()) {
            // 字段校验有错误
            bindingResult.getFieldErrors().forEach(fieldError -> {
                errors.put(fieldError.getField(), fieldError.getDefaultMessage());
            });
            model.addAttribute("errors", errors);
            return "register";
        }

        // 验证码校验
        String code = stringRedisTemplate.opsForValue().get("sms:code:" + memberVO.getMobile());
        if (!memberVO.getCode().equals(code)) {
            errors.put("code", "验证码错误");
            model.addAttribute("errors", errors);
            return "register";
        }

        // 远程调用进行注册
        R register = memberFeignClient.register(memberVO);
        if (register.getCode() != 0) {
            // 注册失败
            errors.put("username", (String) register.get("msg"));
            model.addAttribute("errors", errors);
            return "register";
        }

        return "redirect:http://auth.gulimall.com/login.html";
    }

    @PostMapping(value = {"/login"})
    @SneakyThrows
    public String login(@RequestParam("login-account") String loginAccount, @RequestParam("password") String password, Model model, HttpSession session) {

        // 存储错误信息
        HashMap<String, String> errors = new HashMap<>();

        // 登录 操作
        // 初步校验
        if (StrUtil.isBlank(loginAccount)) {
            errors.put("msg", "请输入账号");
            model.addAttribute("errors", errors);
            return "login";
        }
        if (StrUtil.isBlank(password)) {
            errors.put("msg", "请输入密码");
            model.addAttribute("errors", errors);
            return "login";
        }

        // 远程调用进行登录
        R login = memberFeignClient.login(loginAccount, password);
        if (login.getCode() != 0) {
            // 登录失败
            errors.put("msg", (String) login.get("msg"));
            model.addAttribute("errors", errors);
            return "login";
        }

        // 登录成功
        MemberVO loginMemberData = login.getData(MemberVO.class);

        String stringUserInfo = objectMapper.writeValueAsString(loginMemberData);
        session.setAttribute("loginMember", stringUserInfo);

        return "redirect:http://gulimall.com";
    }
}


